package org.footballmanager.pandafootball.system.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.footballmanager.pandafootball.common.constants.Constants;
import org.footballmanager.pandafootball.common.job.AutoBfJob;
import org.footballmanager.pandafootball.common.job.QuartzManager;
import org.footballmanager.pandafootball.common.util.DateUtils;
import org.footballmanager.pandafootball.system.dao.FootBfinfoDao;
import org.footballmanager.pandafootball.system.domain.*;
import org.footballmanager.pandafootball.system.domain.enums.BFLX;
import org.footballmanager.pandafootball.system.domain.enums.BFZT;
import org.footballmanager.pandafootball.system.domain.enums.SJZT;
import org.footballmanager.pandafootball.system.form.impl.FootBfinfoSearchForm;
import org.footballmanager.pandafootball.system.mapper.FootBfinfoMapper;
import org.footballmanager.pandafootball.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.*;

@Slf4j
@Service("footBfinfoService")
public class FootBfinfoServiceImpl extends ServiceImpl<FootBfinfo> implements FootBfinfoService {
	private static final String MYVIEW = "/hy/footBfinfo/myView";
    private static final String CANGOON = "canGoOn";
    private static final String ZHUTEAM = "zhuTeam";
    private static final String KETEAM = "keTeam";
    private static final String POWERONE = "power1";
    private static final String POWERTWO = "power2";

	@Autowired
	private FootBfinfoDao footBfinfoDao;
    @Autowired
    private FootBfinfoMapper footBfinfoMapper;
	@Autowired
	private FootUserService footUserService;
	@Autowired
	private FootUserPersonService footUserPersonService;
	@Autowired
	private FootClubService footClubService;
	@Autowired
	private FootRankService footRankService;
	@Autowired
	private FootTtService footTtService;
	@Autowired
	private FootTeamService footTeamService;
	@Autowired
	private FootZnxService footZnxService;
	@Autowired
	private FootSjService footSjService;
	@Autowired
	private FootYysService footYysService;

	@Override
	@Transactional
	public int delete(Serializable id, HttpServletRequest request) {
		FootBfinfo t = this.get(id);
		log.info("删除球队报分:" + t.toString());
		if(t.getBfzt().equals(BFZT.HAVE)){
			if(t.getBflx().equals(BFLX.NORMAL)){
                footClubService.deleteEncourage(t, request);
				footUserPersonService.addUseTimes(t.getQd1(), request);
				footUserPersonService.addUseTimes(t.getQd2(), request);
				footClubService.reComputeRanking(request);
			}else if(t.getBflx().equals(BFLX.GRID)){
                footRankService.deleteEncourage(t, request);
				footRankService.reComputeRanking(request);
			}else if(t.getBflx().equals(BFLX.TOP)){
				footTtService.deleteEncourage(t, request);
				footTtService.reComputeRanking(request);
			}else if(t.getBflx().equals(BFLX.HOTBODY)){
				footYysService.setYysData(t, false, request);
				footYysService.addCreditByUserId(t.getQd1(), -1D, request);
				footYysService.addCreditByUserId(t.getQd2(), -2D, request);
			}
		}
		return super.delete(id, request);
	}

	@Override
	@Transactional
	public int updateAll(FootBfinfo t, HttpServletRequest request) {
		log.info("更新球队报分:" + t.toString());
		t.setBfzt(BFZT.HAVE);
		if(t.getBflx().equals(BFLX.NORMAL)){
			footUserPersonService.autoDeletePerson(t.getQd1(), request);
			footUserPersonService.autoDeletePerson(t.getQd2(), request);
            footClubService.addEncourage(t, request);
			footZnxService.sendZnx(t.getQd2(), t.getQd1(), "已确认常规赛比分", footTeamService.getLogoByUserid(t.getQd2()),
					MYVIEW, request);
		}else if(t.getBflx().equals(BFLX.GRID)){
            footRankService.addEncourage(t, request);
			footZnxService.sendZnx(t.getQd2(), t.getQd1(), "已确认排位赛比分", footTeamService.getLogoByUserid(t.getQd2()),
					MYVIEW, request);
		}else if(t.getBflx().equals(BFLX.HOTBODY)){
			footYysService.setYysData(t, true, request);
			footYysService.addCreditByUserId(t.getQd2(), 2D, request);
			footZnxService.sendZnx(t.getQd2(), t.getQd1(), "已确认排位赛比分", footTeamService.getLogoByUserid(t.getQd2()),
					MYVIEW, request);
		}
		return super.updateAll(t, request);
	}

	@Override
	@Transactional
	public int save(FootBfinfo t, HttpServletRequest request) {
        t.setBfzt(BFZT.NOT);
		if(t.getBflx().equals(BFLX.NORMAL)){
			footZnxService.sendZnx(t.getQd1(), t.getQd2(), "请确认常规赛比赛结果",
					null, MYVIEW, request);
		}else if(t.getBflx().equals(BFLX.GRID)){
			footZnxService.sendZnx(t.getQd1(), t.getQd2(), "请确认排位赛比赛结果",
					null, MYVIEW, request);
		}else if(t.getBflx().equals(BFLX.TOP)){
			t.setBfzt(BFZT.HAVE);
			footUserPersonService.autoDeletePerson(t.getQd1(), request);
			footTtService.addEncourage(t, request);
			footZnxService.sendZnx(footUserService.getAdminUserid(), t.getQd1(), "查看天梯赛结果", null,
					MYVIEW, request);
		}else if(t.getBflx().equals(BFLX.HOTBODY)){
			footYysService.addCreditByUserId(t.getQd1(), 1D, request);
			footZnxService.sendZnx(t.getQd1(), t.getQd2(), "请确认热身赛比赛结果",
					null, MYVIEW, request);
		}
        processQuartzTask(t);
		return super.save(t, request);
	}

    private void processQuartzTask(@Valid FootBfinfo footBfinfo){
        if(!footBfinfo.getBflx().equals(BFLX.HOTBODY)){
            Map<String, Object> mapParams = new HashMap<>();
            mapParams.put(Constants.ID, footBfinfo.getId());
            mapParams.put("FootBfinfoService", this);
            Date date = DateUtils.addHours(new Date(),2);
            QuartzManager.addJob("两小时后未确认比赛报分的自动确认报分", AutoBfJob.class, DateUtils.getCron(date), mapParams);
        }
    }

	@Override
	public List<FootUser> findCanBfUser(FootUser user, FootSj sj, Integer type) {
		List<FootUser> list = new ArrayList<>();
        Example example = new Example(FootBfinfo.class);
        Example.Criteria criteria = example.createCriteria();
        Example.Criteria criteria2 = example.createCriteria();
        criteria.andEqualTo("sj", sj.getId());
		if(type != null){
            criteria.andEqualTo("bflx", BFLX.values()[type]);
		}
        criteria.andEqualTo("qd1", user.getId());
        criteria2.andEqualTo("qd2", user.getId());
        example.or(criteria2);
		List<FootBfinfo> bfList = this.findall(example);
		if(bfList != null && !bfList.isEmpty()){
			for(FootBfinfo bf: bfList){
				if(bf.getQd1().equals(user.getId())){
					list.add(footUserService.get(bf.getQd2()));
				}else{
					list.add(footUserService.get(bf.getQd1()));
				}
			}
		}
		return list;
	}

	@Override
	public List<FootBfinfo> getSubmitData(Long userId, Long sj) {
        Example example = new Example(FootBfinfo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", sj);
        Example.Criteria criteria2 = example.createCriteria();
        criteria.andEqualTo("qd1", userId);
        criteria2.andEqualTo("qd2", userId);
        criteria.andNotEqualTo("bflx", BFLX.HOTBODY);
        criteria.andEqualTo("bfzt", BFZT.HAVE);
        example.or(criteria2);
		return this.findall(example);
	}

	@Override
	public List<FootBfinfo> findYysByUserId(Long userId) {
        Example example = new Example(FootBfinfo.class);
        Example.Criteria criteria = example.createCriteria();
        Example.Criteria criteria2 = example.createCriteria();
        criteria.andEqualTo("qd1", userId);
        criteria2.andEqualTo("qd2", userId);
        criteria.andEqualTo("bflx", BFLX.HOTBODY);
        example.or(criteria2);
		return this.findall(example);
	}

	@Override
	public Integer countMissionNumByUserId(Long userId, int missionnum) {
		FootSj sj = footSjService.get(footSjService.getSj());
        Example example = new Example(FootBfinfo.class);
        Example.Criteria criteria = example.createCriteria();
        Example.Criteria criteria2 = example.createCriteria();
        criteria.andEqualTo("sj", sj.getId());
		Date date = new Date();
		criteria.andBetween("createTime", DateUtils.processWithStartOrEnd(date, true), DateUtils.processWithStartOrEnd(date, false));
		criteria.andEqualTo("qd1", userId);
		criteria2.andEqualTo("qd2", userId);
		if(missionnum == 1){
			if(sj.getSjzt().equals(SJZT.NORMAL)){
			    criteria.andEqualTo("bflx", BFLX.NORMAL);
			}else{
                criteria.andEqualTo("bflx", BFLX.GRID);
			}
		}else{
            criteria.andEqualTo("bflx", BFLX.HOTBODY);
		}
        criteria.andEqualTo("bfzt", BFZT.HAVE);
		example.or(criteria2);
		return this.findall(example).size();
	}

	@Override
	public boolean isGoOnBf(Long userId, BFLX bflx) {
        Example example = new Example(FootBfinfo.class);
        Example.Criteria criteria = example.createCriteria();
        Example.Criteria criteria2 = example.createCriteria();
        criteria.andEqualTo("bflx", bflx);
        criteria.andEqualTo("sj", footSjService.getSj());
		if(bflx.equals(BFLX.GRID)){
			Date date = new Date();
            criteria.andBetween("createTime", DateUtils.processWithStartOrEnd(date, true), DateUtils.processWithStartOrEnd(date, false));
            criteria.andEqualTo("qd1", userId);
            criteria2.andEqualTo("qd2", userId);
            example.or(criteria2);
			List<FootBfinfo> list = this.findall(example);
			return list.size() < 2;
		}else{
            criteria.andEqualTo("qd1", userId);
            criteria2.andEqualTo("qd2", userId);
            example.or(criteria2);
			List<FootBfinfo> list = this.findall(example);
			return list.size() < 30;
		}
	}

	@Override
	public boolean isGoOnBf(FootBfinfo t) {
        Example example = new Example(FootBfinfo.class);
        Example.Criteria criteria = example.createCriteria();
        Example.Criteria criteria2 = example.createCriteria();
        criteria.andEqualTo("bflx", BFLX.NORMAL);
        criteria.andEqualTo("sj", footSjService.getSj());
        criteria.andEqualTo("qd1", t.getQd1()).andEqualTo("qd2", t.getQd2());
        criteria2.andEqualTo("qd2", t.getQd1()).andEqualTo("qd1", t.getQd2());
        example.or(criteria2);
		List<FootBfinfo> list = this.findall(example);
		return list.size() < 2;
	}

    /**
     * 翻页方法
     *
     * @param footBfinfoSearchForm 条件
     * @return 列表
     */
    @Override
    public List<FootBfinfo> findall(FootBfinfoSearchForm footBfinfoSearchForm) {
        return footBfinfoMapper.findall(footBfinfoSearchForm);
    }

    @Override
    public FootBfinfo get(Serializable id){
        return footBfinfoMapper.findById(id);
    }

    /**
     * 查询
     *
     * @param entityname           实体类名
     * @param map                  参数
     * @param footBfinfoSearchForm 条件
     */
    @Override
    public void search(String entityname, Model map, FootBfinfoSearchForm footBfinfoSearchForm) {
        map.addAttribute(String.format(Constants.FORMNAME, entityname), footBfinfoSearchForm);
        Page<FootBfinfo> page = PageHelper.startPage(footBfinfoSearchForm.getPageIndex(), footBfinfoSearchForm.getPageSize());
        List<FootBfinfo> list = this.findall(footBfinfoSearchForm);
        map.addAttribute(String.format(Constants.LISTENTITY, entityname), list);
        map.addAttribute(Constants.PI, page.toPageInfo());
    }

    /**
     * 删除所有
     *
     * @param footBfinfoSearchForm 条件
     * @param request              请求
     * @return 类型
     */
    @Override
    public int deleteAll(FootBfinfoSearchForm footBfinfoSearchForm, HttpServletRequest request) {
        int type = 0;
        if(footBfinfoSearchForm.getSelectIds() != null){
            String[] ids = footBfinfoSearchForm.getSelectIds().split(Constants.COMMA);
            for(String id: ids){
                FootBfinfo bf = footBfinfoDao.selectByPrimaryKey(Long.parseLong(id));
                this.delete(Long.parseLong(id), request);
                type = bf.getBflx().ordinal();
            }
        }
        return type;
    }

    /**
     * 添加报分
     *
     * @param user    用户
     * @param map     参数
     * @param type    类型
     * @param request 请求
     */
    @Override
    public String add(FootUser user, Model map, Integer type, HttpServletRequest request) {
        FootBfinfo bf = new FootBfinfo();
        bf.setQd1(user.getId());
        bf.setQd1Name(user.getNike());
        bf.setBflx(BFLX.values()[type]);
        bf.setBfzt(BFZT.NOT);
        bf.setSj(footSjService.getSj());

        boolean canGoOn = false;
        if(type.equals(5)){
            //天梯赛 获取符合条件的战队并随机取一个
            FootTeam team = footUserPersonService.getRandomTeam(user);
            if(null != team){
                bf.setQd2(team.getUserId());
                bf.setQd2Name(team.getUserName());
                bf.setBfzt(BFZT.HAVE);
                String result = footTtService.winner(user.getId(), team.getUserId(), request);
                if(result.contains(":")){
                    String[] res = result.split(":");
                    bf.setJq1(Integer.parseInt(res[0]));
                    bf.setJq2(Integer.parseInt(res[1]));
                    super.save(bf, request);
                    canGoOn = true;
                }else{
                    canGoOn = false;
                }
            }
        }
        map.addAttribute("footBfinfo", bf);
        return processOpenPage(bf, user, canGoOn, request, map);
    }

    private String processOpenPage(FootBfinfo bf, FootUser user, boolean canGoOn, HttpServletRequest request, Model map){
        if(bf.getBflx().equals(BFLX.NORMAL)){
            map.addAttribute(CANGOON, this.isGoOnBf(user.getId(), bf.getBflx()));
            map.addAttribute(ZHUTEAM, footUserPersonService.findFootPersonByUserId(user.getId(), request));
            return "hy/bf/footBfinfo/Add";
        }else if(bf.getBflx().equals(BFLX.GRID)){
            map.addAttribute(CANGOON, this.isGoOnBf(user.getId(), bf.getBflx()));
            map.addAttribute(ZHUTEAM, footUserPersonService.findFootPersonByUserId(user.getId(), request));
            return "hy/bf/footRankbfinfo/Add";
        }else if(bf.getBflx().equals(BFLX.TOP)){
            map.addAttribute(POWERONE, footUserPersonService.getPower(bf.getQd1(), request));
            map.addAttribute(POWERTWO, footUserPersonService.getPower(bf.getQd2(), request));
            map.addAttribute(ZHUTEAM, footUserPersonService.findFootPersonByUserId(user.getId(), request));
            map.addAttribute(KETEAM, footUserPersonService.findFootPersonByUserId(bf.getQd2(), request));
            map.addAttribute(CANGOON, canGoOn);
            return "hy/bf/footTtbfinfo/Add";
        }else if(bf.getBflx().equals(BFLX.HOTBODY)){
            return "hy/bf/footYysbfinfo/Add";
        }
        return null;
    }

    /**
     * 确认报分
     *
     * @param footBfinfo 报分信息
     * @param request    请求
     */
    @Override
    public void makesure(FootBfinfo footBfinfo, HttpServletRequest request) {
        if(footBfinfo.getId() != null){
            FootBfinfo bf = footBfinfoDao.selectByPrimaryKey(footBfinfo.getId());
            bf.setBfzt(BFZT.HAVE);
            this.updateAll(bf, request);
        }
    }

    /**
     * 返回页面
     *
     * @param footBfinfo 报分实体类
     * @param map        参数
     * @param user       用户
     * @param request    请求
     * @return 页面
     */
    @Override
    public String processReturnPage(@Valid FootBfinfo footBfinfo, Model map, FootUser user, HttpServletRequest request) {
        if(footBfinfo.getBflx().equals(BFLX.NORMAL)){
            map.addAttribute(CANGOON, this.isGoOnBf(user.getId(), footBfinfo.getBflx()));
            map.addAttribute(ZHUTEAM, footUserPersonService.findFootPersonByUserId(user.getId(), request));
            return "hy/bf/footBfinfo/Add";
        }else if(footBfinfo.getBflx().equals(BFLX.GRID)){
            map.addAttribute(CANGOON, this.isGoOnBf(user.getId(), footBfinfo.getBflx()));
            map.addAttribute(ZHUTEAM, footUserPersonService.findFootPersonByUserId(user.getId(), request));
            return "hy/bf/footRankbfinfo/Add";
        }else if(footBfinfo.getBflx().equals(BFLX.TOP)){
            map.addAttribute(CANGOON, this.isGoOnBf(user.getId(), footBfinfo.getBflx()));
            map.addAttribute(ZHUTEAM, footUserPersonService.findFootPersonByUserId(user.getId(), request));
            return "hy/bf/footTtbfinfo/Add";
        }else if(footBfinfo.getBflx().equals(BFLX.HOTBODY)){
            return "hy/bf/footYysbfinfo/Add";
        }
        return null;
    }

    /**
     * 处理错误页面
     *
     * @param footBfinfo    实体类
     * @param bindingResult 校验
     * @param request       请求
     */
    @Override
    public void processError(@Valid FootBfinfo footBfinfo, BindingResult bindingResult, HttpServletRequest request) {
        if(footBfinfo.getBflx().equals(BFLX.NORMAL)){
            List<FootPerson> list = footUserPersonService.findFootPersonByUserId(footBfinfo.getQd1(), request);
            if(list.size() < 18){
                bindingResult.rejectValue("qd1", Constants.MISFORMAT, "自己的球队未满18人，不能报分");
            }
            List<FootPerson> list2 = footUserPersonService.findFootPersonByUserId(footBfinfo.getQd2(), request);
            if(list2.size() < 18){
                bindingResult.rejectValue("qd1", Constants.MISFORMAT, "对手的球队未满18人，不能报分");
            }
        }
    }

    /**
     * 返回列表页面
     *
     * @param footBfinfoSearchForm 条件
     * @param isSearchPage 是否是查询页面
     * @return 页面
     */
    @Override
    public String searchPage(FootBfinfoSearchForm footBfinfoSearchForm, boolean isSearchPage) {
        if(footBfinfoSearchForm.getBflx().equals(BFLX.NORMAL)){
            return "hy/bf/footBfinfo/" + (isSearchPage ? "List" : "MyList");
        }else if(footBfinfoSearchForm.getBflx().equals(BFLX.GRID)){
            return "hy/bf/footRankbfinfo/" + (isSearchPage ? "List" : "MyList");
        }else if(footBfinfoSearchForm.getBflx().equals(BFLX.HOTBODY)){
            return "hy/bf/footYysbfinfo/" + (isSearchPage ? "List" : "MyList");
        }else if(footBfinfoSearchForm.getBflx().equals(BFLX.TOP)){
            return "hy/bf/footTtbfinfo/" + (isSearchPage ? "List" : "MyList");
        }
        return null;
    }

    /**
     * 查看页面
     *
     * @param id                   主键
     * @param map                  参数
     * @param request              请求
     * @param footBfinfoSearchForm 条件
     * @param isViewPage           是否是查看页面
     * @return 页面
     */
    @Override
    public String view(Long id, Model map, HttpServletRequest request, FootBfinfoSearchForm footBfinfoSearchForm, boolean isViewPage) {
        FootBfinfo bf = footBfinfoDao.selectByPrimaryKey(id);
        map.addAttribute(ZHUTEAM, footUserPersonService.findFootPersonByUserId(bf.getQd1(), request));
        map.addAttribute(KETEAM, footUserPersonService.findFootPersonByUserId(bf.getQd2(), request));
        map.addAttribute("footBfinfo", bf);
        if(bf.getBflx().equals(BFLX.NORMAL)){
            return "hy/bf/footBfinfo/" + (isViewPage ? "View" : "MyView");
        }else if(bf.getBflx().equals(BFLX.GRID)){
            return "hy/bf/footRankbfinfo/" + (isViewPage ? "View" : "MyView");
        }else if(bf.getBflx().equals(BFLX.HOTBODY)){
            return "hy/bf/footYysbfinfo/" + (isViewPage ? "View" : "MyView");
        }else if(bf.getBflx().equals(BFLX.TOP)){
            map.addAttribute(POWERONE, footUserPersonService.getPower(bf.getQd1(), request));
            map.addAttribute(POWERTWO, footUserPersonService.getPower(bf.getQd2(), request));
            return "hy/bf/footTtbfinfo/" + (isViewPage ? "View" : "MyView");
        }
        return null;
    }
}
